﻿using System;
using System.Windows.Interop;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using SlimDX.Direct3D10;
using System.Diagnostics;
using SlimDX.DXGI;
using System.Collections;
using SlimDX;
using SlimDX.Windows;
using System.Text;

namespace EikonLeap
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);

        [DllImport("user32.dll")]
        static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn,
            IntPtr lParam);

        static IEnumerable<IntPtr> EnumerateProcessWindowHandles(int processId)
        {
            var handles = new List<IntPtr>();

            foreach (ProcessThread thread in Process.GetProcessById(processId).Threads)
                EnumThreadWindows(thread.Id,
                    (hWnd, lParam) => { handles.Add(hWnd); return true; }, IntPtr.Zero);

            return handles;
        }

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);


        static IEnumerable<IntPtr> getEikonPopups(IEnumerable<IntPtr> inputs)
        {
            var popupHandles = new List<IntPtr>();
            foreach (IntPtr handle in inputs)
            {
                StringBuilder sb = new StringBuilder(100);
                GetClassName(handle, sb, sb.Capacity);
                if (sb.ToString() == "KobraPopupWndClass")
                {
                    popupHandles.Add(handle);
                }
                
            }

            return popupHandles;
        }

        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            var form = new SlimDX.Windows.RenderForm("EikonLeap");
            form.ClientSize = new System.Drawing.Size(1280, 720);
            //form.FormBorderStyle = FormBorderStyle.None;
            //form.WindowState = FormWindowState.Maximized;
            System.Windows.Forms.Cursor.Position = form.PointToScreen(new System.Drawing.Point(form.ClientSize.Width / 2, form.ClientSize.Height / 2));
            Input input = new Input(form);
            IEnumerable<IntPtr> handles = EnumerateProcessWindowHandles(Process.GetProcessesByName("eikon").First().Id);
            //IEnumerable<IntPtr> handles = EnumerateProcessWindowHandles(Process.GetProcessesByName("kobra").First().Id);
            IEnumerable<IntPtr> eikonPopupHandles = getEikonPopups(handles);
            var lhandles = eikonPopupHandles.ToList();
            using (Renderer renderer = new Renderer(form))
            {
                Scene scene = new Scene();
                //Create Viewport
                Viewport viewport = new Viewport(0, 0, form.ClientSize.Width, form.ClientSize.Height);
                Camera camera = new Camera();
                camera.Eye = new Vector3(0.0f, 0.0f, 8.0f);
                scene.Cameras.Add("mainCamera", camera);
                ScreenPlate plate = new ScreenPlate();
                ScreenPlate plate2 = new ScreenPlate();
                ScreenPlate plate3 = new ScreenPlate();
                //ScreenPlate plate4 = new ScreenPlate();
                //ScreenPlate plate5 = new ScreenPlate();
                plate.SphericalPosition = new Vector3(5.0f, 0.0f, 0.0f);
                plate2.SphericalPosition = new Vector3(5.0f, (float)Math.PI*0.5f, 0.0f);
                plate3.SphericalPosition = new Vector3(5.0f, (float)Math.PI * 1.0f, 0.0f);
                //plate4.SphericalPosition = new Vector3(5.0f, (float)Math.PI * 1.5f, 0.0f);`
                //plate5.SphericalPosition = new Vector3(5.0f, (float)Math.PI * 0.5f, 1.0f);
                scene.AddObject("plate", plate);
                scene.AddObject("plate2", plate2);
                scene.AddObject("plate3", plate3);

                //scene.AddObject("plate4", plate4);
                //scene.AddObject("plate5", plate5);
                form.ClientSizeChanged += (o, e) =>
                {
                    renderer.OnResize(form.ClientSize.Width, form.ClientSize.Height);
                };

                //Main Loop
                DateTime lastFrame = DateTime.Now;
                MessagePump.Run(form, () =>
                    {
                        TimeSpan elapsedTime = DateTime.Now - lastFrame;
                        lastFrame = DateTime.Now;
                        scene.Update(elapsedTime.TotalMilliseconds, input);
                        renderer.Render(scene);
                    }
                );
            }
        }
    }
}
